using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using WebAPI.Dtos;

namespace WebAPI.Controllers;

[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase {
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly UserManager<IdentityUser> _userManager;

    public AuthController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager) {
        _signInManager = signInManager;
        _userManager = userManager;
    }

    /**
     * 登录
     */
    [HttpPost("login")]
    public async Task<IActionResult> Login([FromBody] LoginDto loginDto) {
        // 通过PasswordSignInAsync，验证用户名与密码
        //bool isPersistent：是否持久化登录状态 表示用户选择了“记住我”（Remember Me）选项
        //bool lockoutOnFailure：表示是否在登录失败时触发锁定机制
        var result = _signInManager.PasswordSignInAsync(loginDto.UserName, loginDto.Password, true, false);
        //如果成功 返回结果
        if (result.Result.Succeeded) {
            //定义jwt的payload部分 创建一个包含用户声明的列表 这种做法常用于身份验证和授权过程中
            var claims = new[] {
                new Claim(ClaimTypes.Name, loginDto.UserName)
            };
            //生成token
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConst.SecurityKey));//创建对称密钥
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);//创建签名凭证
            //创建JWT安全令牌
            var securityToken = new JwtSecurityToken(
                issuer:JwtConst.Issuer,//设置发行者
                audience:JwtConst.Audience,//设置接收者
                claims:claims,//设置声明 包含用户的信息
                expires:DateTime.Now.AddDays(1),//设置过期时间
                signingCredentials:credentials//设置签名凭证
                );
            var token = new JwtSecurityTokenHandler().WriteToken(securityToken);
            return Ok(token);
        }
        else {
            return Ok("登录失败");
        }
    }

    /**
     * 根据用户昵称，获取用户信息
     */
    [HttpGet("{userName}")]
    [Authorize]
    public async Task<IActionResult> GetUserByUserName(string userName) {
        var result = await _userManager.FindByNameAsync(userName);
        return Ok(result);
    }
}